package com.ng.framework.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;
import java.util.zip.ZipOutputStream;

import org.apache.log4j.Logger;

public final class NGZipUtil {

	private static Logger LOG = Logger.getLogger(NGZipUtil.class);

	private NGZipUtil() {
	}

	public static void unzip(String zipPath, String outputFolderPath) {
		
		int count =0;

		byte[] buffer = new byte[1024];

		try {

			// create output directory is not exists
			File folder = new File(outputFolderPath);
			if (!folder.exists()) {
				folder.mkdir();
			}

			// get the zip file content
			ZipInputStream zis = new ZipInputStream(new FileInputStream(zipPath));
			// get the zipped file list entry
			ZipEntry ze = zis.getNextEntry();

			while (ze != null) {

				String fileName = ze.getName();
				File newFile = new File(outputFolderPath + File.separator + fileName);

				LOG.debug("file unzip : " + newFile.getAbsoluteFile());

				// create all non exists folders
				// else you will hit FileNotFoundException for compressed folder
				new File(newFile.getParent()).mkdirs();

				FileOutputStream fos = new FileOutputStream(newFile);

				int len;
				while ((len = zis.read(buffer)) > 0) {
					fos.write(buffer, 0, len);
				}

				fos.close();
				ze = zis.getNextEntry();
				count ++;
			}

			zis.closeEntry();
			zis.close();

			LOG.debug("Everything went ok. "+count+ " file/s extracted");

		} catch (IOException ex) {
			ex.printStackTrace();
		}
	}
	public static void zipFolder(String sourceFolderPath, String outputFilePath) {
		try {

			// create byte buffer
			byte[] buffer = new byte[1024];
			/*
			 * To create a zip file, use
			 * 
			 * ZipOutputStream(OutputStream out) constructor of ZipOutputStream class.
			 */

			// create object of FileOutputStream
			FileOutputStream fout = new FileOutputStream(outputFilePath);

			// create object of ZipOutputStream from FileOutputStream
			ZipOutputStream zout = new ZipOutputStream(fout);

			// create File object from directory name
			File dir = new File(sourceFolderPath);

			// check to see if this directory exists
			if (!dir.isDirectory()) {
				LOG.warn(sourceFolderPath + " is not a directory");
			} else {
				File[] files = dir.listFiles();

				for (int i = 0; i < files.length; i++) {
					LOG.debug("Adding " + files[i].getName());

					// create object of FileInputStream for source file
					FileInputStream fin = new FileInputStream(files[i]);

					/*
					 * To begin writing ZipEntry in the zip file, use
					 * 
					 * void putNextEntry(ZipEntry entry) method of ZipOutputStream class.
					 * 
					 * This method begins writing a new Zip entry to the zip file and positions the stream to the start of the entry data.
					 */

					zout.putNextEntry(new ZipEntry(files[i].getName()));

					/*
					 * After creating entry in the zip file, actually write the file.
					 */
					int length;

					while ((length = fin.read(buffer)) > 0) {
						zout.write(buffer, 0, length);
					}

					/*
					 * After writing the file to ZipOutputStream, use
					 * 
					 * void closeEntry() method of ZipOutputStream class to close the current entry and position the stream to write the next entry.
					 */

					zout.closeEntry();

					// close the InputStream
					fin.close();
				}
			}

			// close the ZipOutputStream
			zout.close();

			LOG.debug("Zip file has been created!");

		} catch (Exception exception) {
			LOG.error(exception);
		}

	}
}
